﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using System.IO;

namespace IBS2ibsImport
{
    public partial class Service1 : ServiceBase
    {
        private Timer timer = null;

        public Service1()
        {
            InitializeComponent();
            try
            {
                if (!EventLog.SourceExists(this.ServiceName + "_log"))
                    EventLog.CreateEventSource(this.ServiceName, this.ServiceName + "_log");
            }
            catch { }
            serviceLog.Source = this.ServiceName + "_log";
            serviceLog.Log = this.ServiceName + "_log";
        }

        protected override void OnStart(string[] args)
        {
            serviceLog.WriteEntry(this.ServiceName + " запущен");
            Properties.Settings.Default.Reload();
            var ExecuteTimes = Properties.Settings.Default.ExecuteTimes;
            if (Properties.Settings.Default.ExecuteImmediately)
                ExecuteTimes.Add(DateTime.Now.AddMinutes(1).ToString("HH:mm"));

            timer = new Timer();
            timer.Elapsed += new ElapsedEventHandler(OnElapsedTime);
            timer.Interval = TimerUtil.GetNewTimerInterval(ExecuteTimes);
            timer.Enabled = true;
        }

        protected override void OnStop()
        {
            serviceLog.WriteEntry(this.ServiceName + " остановлен");
            timer.Stop();
            timer.Close();
        }

        /// <summary>
        /// При срабатывании таймера
        /// </summary>
        /// <param name="source"></param>
        /// <param name="e"></param>
        private void OnElapsedTime(object source, ElapsedEventArgs e)
        {
            // Останавливаем таймей и стартуем выполнение выгрузки
            timer.Stop();
            Process();
            // Интервал таймера
            Properties.Settings.Default.Reload();
            timer.Interval = TimerUtil.GetNewTimerInterval(Properties.Settings.Default.ExecuteTimes);
            timer.Start();
        }


        public virtual string GetFormattedString(string str, byte lenght, string separator, bool leftAlign)
        {
            if (leftAlign)
            {
                if (String.IsNullOrEmpty(str))
                    return "".PadRight(lenght, Convert.ToChar(separator));
                if (str.Length == lenght)
                    return str;
                if (str.Length > lenght)
                    return str.Remove(lenght);
                if (str.Length < lenght)
                    return str.PadRight(lenght, Convert.ToChar(separator));
            }
            else
            {
                if (String.IsNullOrEmpty(str))
                    return "".PadLeft(lenght, Convert.ToChar(separator));
                if (str.Length == lenght)
                    return str;
                if (str.Length > lenght)
                    return str.Remove(lenght);
                if (str.Length < lenght)
                    return str.PadLeft(lenght, Convert.ToChar(separator));
            }
            return null;
        }


        private void Process()
        {
            try
            {
                serviceLog.WriteEntry("Запуск процедуры выгрузки накладных в формате IbsImport");
                string IBSConnectionString = Properties.Settings.Default.IBSConnectionString;
                var path2IbsImport = Properties.Settings.Default.path2IbsImport;
                if (!Directory.Exists(path2IbsImport))
                    Directory.CreateDirectory(path2IbsImport);

                var ibs = new IBS.IbsDataContext(IBSConnectionString);

                var SaleOrderList = ibs.GetSaleOrders(IBS.IMPORTTYPE.IbsImport);

                foreach (var saleOrder in SaleOrderList)
                {
                    try
                    {
                        //сообщение о несоответствии цен
                        if (saleOrder.INVOICE_ID != 0)
                        {
                            var orders = ibs.GetSaleOrderMsg(saleOrder.INVOICE_ID).ToList();
                            //var msg = String.Empty;
                            if (orders.Count > 0)
                            {
                                StringBuilder resultString = new StringBuilder();
                                //msg = String.Format("{0}ID Товара{0}Цена в документе{0}Цена в справочнике{0}Цена, отправленная на АЗС{1}", "     ", Environment.NewLine);
                                resultString.Append(String.Format("{0}ID Товара\tЦена в документе\tЦена в справочнике\tЦена, отправленная на АЗС{1}", "     ", Environment.NewLine));
                                orders.ForEach(r =>
                                {
                                    resultString.Append(String.Concat(GetFormattedString(r.ITEM_KEY.ToString(), 14, " ", false), "\t\t"));
                                    resultString.Append(String.Concat(GetFormattedString(r.PRICE.ToString(), 16, " ", false), "\t\t"));
                                    resultString.Append(String.Concat(GetFormattedString(r.ACTUAL_PRICE.ToString(), 18, " ", false), "\t\t"));
                                    if (r.PRICE < r.ACTUAL_PRICE)
                                    {
                                        resultString.Append(String.Concat(GetFormattedString(r.PRICE.ToString(), 25, " ", false), Environment.NewLine));
                                    }
                                    else
                                    {
                                        resultString.Append(String.Concat(GetFormattedString(r.ACTUAL_PRICE.ToString(), 25, " ", false), Environment.NewLine));
                                    }
                                    // msg += String.Format("ID = {0} \tЦена в документе = {1} \tЦена в справочнике = {2} \tОтрпавлена на АЗС = {3}\n", r.ITEM_KEY, r.PRICE, r.ACTUAL_PRICE);
                                }

                                );

                                var subject = String.Format("Предупреждение о расхождении цены по документу № {0}", orders.First().DOC_NUMBER);
                                var body = String.Format(@"Контрагент: {1} ({2}){0}
Документ: {3} от {4} {0}АЗС: {6} - {7} ({5}) {0}

Сумма накладной поставщика: {8} {0}
Сумма накладной после подстановки из справочника: {9} 
Сумма, отправленная на станцию: {10} {0}{0}

{11}",
                                                                string.Empty,                                  //0
                                                                orders.First().SUPNAME,                               //1
                                                                orders.First().COMPANY_KEY,                           //2
                                                                orders.First().DOC_NUMBER,                            //3
                                                                orders.First().DOC_DATE.ToString("dd.MM.yyyy"),       //4
                                                                orders.First().LOCATION_KEY,                          //5
                                                                orders.First().RCCODE,                                //6
                                                                orders.First().SITENAME,                              //7
                                                                orders.First().TOTAL,                                 //8
                                                                orders.First().TOTAL_ACTUAL,                          //9
                                                                orders.First().TOTAL < orders.First().TOTAL_ACTUAL ? orders.First().TOTAL : orders.First().TOTAL_ACTUAL, //10
                                                                resultString.ToString());                             //11

                                var managers = ibs.GetManagerInfo(orders.First().COMPANY_KEY).ToList();

                                managers.ForEach(r =>
                                {
                                    ibs.SendMail("HelpDeskDS@tnk-bp.com", r.EMAIL, subject, body);
                                });

                                var siteEmail = orders.First().RCCODE + "m@mos.tnk-bp.ru";
                                ibs.SendMail("HelpDeskDS@tnk-bp.com", siteEmail, subject, body);
                            }
                        }
                        var ibsImportData = ibs.GetIBSImport(saleOrder.INVOICE_ID);
                        var fileName = String.Empty;
                        var firstRun = true;
                        serviceLog.WriteEntry(String.Format("Выгрузка INVOICE_ID = {0}", saleOrder.INVOICE_ID, ibsImportData));
                        Impersonation.Logon("sqladmin", "MOS", "12345678");
                        foreach (var line in ibsImportData)
                        {
                            if (!Directory.Exists(@"\\" + line.IP + path2IbsImport + @"\"))
                                Directory.CreateDirectory(@"\\" + line.IP + path2IbsImport + @"\");
                           

                            fileName = @"\\" + line.IP + path2IbsImport + @"\" + line.COMPANY_KEY + "_" + line.DOC_NUMBER + "_" + line.DOC_DATE.ToString("yyyy.MM.dd") + ".txt";
                            
                            if (File.Exists(fileName) && firstRun)
                                File.Delete(fileName);
                            
                            firstRun = false;

                            line.SerializeToFile(fileName);
                        }
                        Impersonation.Logoff();

                        serviceLog.WriteEntry(String.Format("Файл сохранен: {0}", fileName), EventLogEntryType.Information);

                        ibs.UpdateStatus(saleOrder.INVOICE_ID);
                    }
                    catch (Exception ex)
                    {
                        serviceLog.WriteEntry(String.Format("Ошибка при записи файла:\nMessage = '{0}'\nInnerException = '{1}'\nSource = '{2}'\n", ex.Message, ex.InnerException, ex.Source), EventLogEntryType.Error);
                    }
                }
            }
            catch (Exception ex)
            {
                serviceLog.WriteEntry(String.Format("В процедуре формирования файла IbsImport произошла ошибка:\nMessage = '{0}'\nInnerException = '{1}'\nSource = '{2}'\n", ex.Message, ex.InnerException, ex.Source), EventLogEntryType.Error);
            }
            finally
            {
                serviceLog.WriteEntry("Процедура выгрузки накладных в формате IbsImport завершена");
            }
        }
    }
}
